package com.financial.business.balance.service.gy.impl;

import com.financial.business.balance.config.GYAccessTokenConfig;
import com.financial.business.balance.config.UrlConfig;
import com.financial.business.balance.connector.SysconfigFeign;
import com.financial.business.balance.constants.FinancialPayBalanceEnumConstants;
import com.financial.business.balance.constants.FinancialPaymentBalanceEnumConstants;
import com.financial.business.balance.dao.FinancialGYPayBalanceDao;
import com.financial.business.balance.domain.FinancialGYPayBalanceDO;
import com.financial.business.balance.dto.FinancialGYBalanceDTO;
import com.financial.business.balance.service.gy.FinancialGYBalancePayService;
import com.financial.business.balance.utils.*;
import com.financial.business.balance.utils.apiresult.ApiResult;
import com.financial.business.balance.utils.apiresult.ApiResultCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author WANGNING
 * @Email wyn20140226@aliyun.com
 * @Description //够样余额业务
 * @Date 2019/12/5 16:50
 */
@Service
public class FinancialGYBalancePayServiceImpl implements FinancialGYBalancePayService {
    public static final Logger logger = LoggerFactory.getLogger(FinancialGYBalancePayServiceImpl.class);
    @Autowired
    private SysconfigFeign sysconfigFeign;

    @Autowired
    private GYAccessTokenConfig gyAccessTokenConfig;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private FinancialGYPayBalanceDao financialGYPayBalanceDao;

    @Autowired
    private HttpClientUtils httpClientUtils;

    /**
     * 够样余额
     *
     * @param requestParam
     * @return
     */
    @Override
    public ApiResult pay(String requestParam) {
        logger.info("FinancialGYBalanceServiceImpl.pay()-----获取够样支付类型为：" + requestParam);
        FinancialGYBalanceDTO financialGYBalanceDTO = JsonUtils.convertBean(requestParam, FinancialGYBalanceDTO.class);
        Map<String, Object> params = JsonUtils.jsonToMap(requestParam);
        /*支付金额*/
        Object tempParam = params.get("total_amount");
        String totalAmountStr = tempParam == null ? null : tempParam.toString();
        /*三方支付专用的交易单号*/
        tempParam = params.get("out_trade_no");
        String outTradeNo = tempParam == null ? null : tempParam.toString();
        /*商品的标题*/
        tempParam = params.get("subject");
        String subject = tempParam == null ? null : tempParam.toString();
        /*支付类型*/
        tempParam = params.get("pay_type");
        String payType = tempParam == null ? null : tempParam.toString();
        /*对接平台商户号*/
        tempParam = params.get("store_no");
        String storeNo = tempParam == null ? null : tempParam.toString();
        /*平台支付单号*/
        tempParam = params.get("pay_id");
        String payId = tempParam == null ? null : tempParam.toString();
        /*支付通道费用*/
        tempParam = params.get("pay_fee");
        String payFeeStr = tempParam == null ? null : tempParam.toString();
        /*回执地址*/
        tempParam = params.get("notify_url");
        String notifyUrl = tempParam == null ? null : tempParam.toString();
        /*商户编码*/
        tempParam = params.get("customer_no");
        String customerNo = tempParam == null ? null : tempParam.toString();
        /*现在支付渠道类型编码*/
        tempParam = params.get("pay_channel_no");
        String payChannelNo = tempParam == null ? null : tempParam.toString();
        /*对接平台编码*/
        tempParam = params.get("platform_no");
        String platformNo = tempParam == null ? null : tempParam.toString();
        if (StringUtils.isBlank(totalAmountStr) || StringUtils.isBlank(outTradeNo)
                || StringUtils.isBlank(subject) || StringUtils.isBlank(payType)
                || StringUtils.isBlank(customerNo) || StringUtils.isBlank(storeNo)
                || StringUtils.isBlank(payId) || StringUtils.isBlank(payFeeStr)
                || StringUtils.isBlank(notifyUrl) || StringUtils.isBlank(platformNo)
                || StringUtils.isBlank(payChannelNo)) {
            /*对所传字段进行非空校验判断*/
            logger.info("FinancialGYBalanceServiceImpl.pay---金融中心余额支付信息校验是否为空:" + ValidateUtils.validateProperty(financialGYBalanceDTO));
            return ApiResult.failure(ValidateUtils.validateProperty(financialGYBalanceDTO));
        }
        try {
            /*获取够样支付平台信息*/
            ApiResult apiResult = sysconfigFeign.platfromInfo(payChannelNo);
            String apiResultMsg = (String) apiResult.getResult();
            if (apiResult.getCode() == FinancialPaymentBalanceEnumConstants.ENUM_CODE_SUC || (apiResultMsg != null && apiResultMsg != "")) {
                /*缓存中获取token*/
                String resultAccessToken;
                Object object = redisUtils.getValue("financialAccessToken");
                /*获取每个参数信息*/
                Map<String, Object> map = JsonUtils.jsonToMap(apiResultMsg);
                String platfromNo = (String) map.get("platfrom_no");
                String platformName = (String) map.get("platform_name");
                String passWord = (String) map.get("pass_word");
                String secret = (String) map.get("secret");
                if (null == object) {
                    String sign = MD5Utils.md5(platformName + platfromNo + passWord + secret);
                    resultAccessToken = gyAccessTokenConfig.getGYAccessToken(platformName, passWord, secret, sign);
                    logger.info("FinancialGYBalanceServiceImpl.pay()-----优店余额支付获取金融中心token" + resultAccessToken);
                } else {
                    resultAccessToken = (String) object;
                }
                /*对分账所有的金额进行精确度设置，保留两位小数*/
                /*支付总金额*/
                BigDecimal totalAmount = new BigDecimal(totalAmountStr).setScale(2, RoundingMode.HALF_UP);
                /*手续费金额*/
                BigDecimal payFee = new BigDecimal(payFeeStr).setScale(2, RoundingMode.HALF_UP);
                /*保存数据初始化*/
                FinancialGYPayBalanceDO financialGYPayBalanceDO = new FinancialGYPayBalanceDO();
                /*落库前通过订单号检查支付单是否存在*/
                FinancialGYPayBalanceDO financialGYPayBalanceDOInfo = financialGYPayBalanceDao.getOne(outTradeNo);
                int res;
                if (financialGYPayBalanceDOInfo != null) {
                    logger.info("FinancialGYBalancePayServiceImpl.pay()-----通过订单号查库数据存在,执行更新操作");
                    /*从数据库获取支付状态*/
                    String state = financialGYPayBalanceDOInfo.getState();
                    logger.info("FinancialGYBalancePayServiceImpl.pay()-----通过订单号查库数据历史状态,订单号:{},订单状态:{}", outTradeNo, state);
                    if (state.equals(FinancialPayBalanceEnumConstants.ENUM_STATE_SUC)) {
                        logger.info("FinancialGYBalancePayServiceImpl.pay()-----通过订单号查库数据历史状态为支付成功");
                        return ApiResult.success(ApiResultCode.HISTORYORDER,financialGYPayBalanceDOInfo.getReturnMessage());
                    } else {
                        logger.info("FinancialGYBalancePayServiceImpl.pay()-----通过订单号查库数据历史状态为支付不成功，更新数据");
                        Map<String, Object> updateMap = new HashMap();
                        updateMap.put("outTradeNo", outTradeNo);
                        updateMap.put("gmtModified", new Date());
                        updateMap.put("state",FinancialPayBalanceEnumConstants.ENUM_STATE_WAIT);
                        updateMap.put("returnMessage",FinancialPayBalanceEnumConstants.ENUM_RETURNMESSAGE_FAIL);
                        res = financialGYPayBalanceDao.updateInfo(updateMap);
                    }
                } else {
                    logger.info("FinancialGYBalancePayServiceImpl.pay()-----通过订单号查库数据不存在,执行创建操作");
                    financialGYPayBalanceDO.setGmtCreate(new Date());
                    financialGYPayBalanceDO.setIsDelete(FinancialPayBalanceEnumConstants.ENUM_ISDELETE_UNDEL);
                    financialGYPayBalanceDO.setCustomerId(customerNo);
                    financialGYPayBalanceDO.setOutTradeNo(outTradeNo);
                    financialGYPayBalanceDO.setPayId(payId);
                    financialGYPayBalanceDO.setPayFee(payFee);
                    financialGYPayBalanceDO.setPayType(payType);
                    financialGYPayBalanceDO.setPlatformNo(platformNo);
                    financialGYPayBalanceDO.setResqContent(requestParam);
                    financialGYPayBalanceDO.setTotalAmount(totalAmount);
                    financialGYPayBalanceDO.setStoreNo(storeNo);
                    financialGYPayBalanceDO.setState(FinancialPayBalanceEnumConstants.ENUM_STATE_WAIT);
                    financialGYPayBalanceDO.setReturnMessage(FinancialPayBalanceEnumConstants.ENUM_RETURNMESSAGE_FAIL);
                    res = financialGYPayBalanceDao.save(financialGYPayBalanceDO);
                }
                if (res > 0) {
                    logger.info("FinancialGYBalanceServiceImpl.pay()-----保存金融中心数据信息成功！");
                    /*拼接请求参数对接够样平台*/
                    Map<String, Object> requestMap = new HashMap<>();
                    requestMap.put("customerUuid", customerNo);
                    requestMap.put("orderNum", outTradeNo);
                    requestMap.put("payMoney", totalAmount);
                    requestMap.put("registBusNum", platfromNo);
                    requestMap.put("accessToken", resultAccessToken);
                    //余额平台回调地址
                    logger.info("FinancialGYBalanceServiceImpl.pay()-----拼接请求参数对接够样平台:" + JsonUtils.objectToJson(requestMap));
                    String result = httpClientUtils.doPost(UrlConfig.BALANCE_GY_PREPAY_URL, requestMap);
                    Map<String, Object> resultMap = JsonUtils.jsonToMap(result);
                    /*更改数据库状态*/
                    Map<String, Object> updateMap = new HashMap();
                    updateMap.put("outTradeNo", outTradeNo);
                    updateMap.put("gmtModified", new Date());
                    updateMap.put("returnMessage", result);
                    if (!FinancialPayBalanceEnumConstants.ENUM_GYRETURNCODE_SUC.equals(resultMap.get("return_code"))) {
                        updateMap.put("state", FinancialPayBalanceEnumConstants.ENUM_STATE_FAIL);
                        financialGYPayBalanceDao.updateInfo(updateMap);
                        return ApiResult.failure(result);
                    }
                    logger.info("FinancialGYBalanceServiceImpl.pay()-----余额预支付信息结果:" + requestMap.get("customerUuid") + "---" + JsonUtils.jsonToMap(result));
                    String prePayInfoMsg = resultMap.get("prePayInfoDO").toString();
                    updateMap.put("state", FinancialPayBalanceEnumConstants.ENUM_STATE_SUC);
                    financialGYPayBalanceDao.updateInfo(updateMap);
                    /*返回信息给调用端*/
                    logger.info("FinancialGYBalanceServiceImpl.pay()-----返回信息给调用端:" + prePayInfoMsg);
                    return ApiResult.success(prePayInfoMsg);
                } else {
                    logger.info("FinancialGYBalanceServiceImpl.pay()-----保存金融中心数据信息失败！");
                    return ApiResult.failure(financialGYPayBalanceDOInfo.getReturnMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("FinancialGYBalanceServiceImpl.pay()-----金融中心数据信息失败:" + e.getMessage());
        }
        return ApiResult.failure(requestParam);
    }

    /**
     * 查询一条支付信息
     *
     * @param paramMap
     * @return
     */
    @Override
    public String query(Map<String, Object> paramMap) {

        return financialGYPayBalanceDao.query(paramMap);
    }
}
